package org.example.task.controller;


import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.task.converter.UserConverterMapper;
import org.example.task.model.dto.PageDTO;
import org.example.task.model.dto.user.LoginDTO;
import org.example.task.model.dto.user.UpdateUserDTO;
import org.example.task.model.dto.user.UserRegisterDTO;
import org.example.task.model.po.LoginUser;
import org.example.task.model.po.User;
import org.example.task.model.query.UserPageQuery;
import org.example.task.model.vo.R;
import org.example.task.model.vo.user.UserPageVO;
import org.example.task.model.vo.user.UserVO;
import org.example.task.service.IUserService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

/**
 * 用户模块
 *
 * @module 用户模块
 */
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
    private final UserConverterMapper userConverterMapper;
    private final IUserService userService;
    private final PasswordEncoder passwordEncoder;

    /**
     * 注册接口
     *
     * @param registerDTO 表单数据
     * @return 结果
     */
    @PostMapping("/auth/register")
    public R register(@Valid @RequestBody UserRegisterDTO registerDTO) {
        User user = userConverterMapper.userRegisterDTOToUser(registerDTO);
        user.setCreateTime(LocalDateTime.now());
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        boolean save = userService.save(user);
        if (save) {
            return R.success();
        }
        return R.error("注册失败");
    }

    /**
     * 登录接口
     *
     * @param loginDTO 表单数据
     * @return 返回token
     */
    @PostMapping("/auth/login")
    public R login(@Valid @RequestBody LoginDTO loginDTO) {
        User user = userConverterMapper.loginDTOToUser(loginDTO);
        String token = userService.login(user);
        return R.success(token);
    }

    /**
     * 获取用户信息接口
     *
     * @return 用户信息
     */
    @GetMapping("/info")
    public R<UserVO> getUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        UserVO userVO = userConverterMapper.userToUserVO(loginUser.getUser());
        return R.success(userVO);
    }

    /**
     * 更新用户信息接口
     *
     * @param updateUserDTO 更新数据
     * @return 结果
     */
    @PreAuthorize("hasAuthority('user_edit')")
    @PutMapping
    public R modifyUser(@Valid @RequestBody UpdateUserDTO updateUserDTO) {
        User user = userConverterMapper.updateUserDTOToUser(updateUserDTO);
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        user.setUserId(loginUser.getUser().getUserId());
        boolean flag = userService.saveOrUpdate(user);
        if (flag) {
            return R.success();
        }
        return R.error("更新失败");
    }

    /**
     * 退出登录接口
     *
     * @return 是否成功
     */
    @GetMapping("/logout")
    public R logout() {
        boolean flag = userService.logout();
        if (flag) {
            return R.success();
        }
        return R.error("退出失败");
    }

    /**
     * 获取用户列表
     *
     * @param userPageQuery 分页请求数据
     * @return 分页查询结果
     */
    @PreAuthorize("hasAuthority('user_list')")
    @GetMapping("/list")
    public R<PageDTO<UserPageVO>> getUserPage(@Valid @RequestBody UserPageQuery userPageQuery) {
        PageDTO<UserPageVO> result = userService.getUserPage(userPageQuery);
        return R.success(result);
    }
}
